home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.4d7 source / NCSA⁄BYU TCP⁄IP / confile.c < prev    next >
Text File  |  1991-12-18  |  35KB  |  1,545 lines

  1. /*
  2. *   Confile.c
  3. *   Split from util.c 5/88
  4. *   Reads and stores the appropriate information for the config file
  5. *
  6. *   version 2, full session layer, TK started 6/17/87
  7. *
  8. ****************************************************************************
  9. *                                                                          *
  10. *      part of:                                                            *
  11. *      Network kernel for NCSA Telnet                                      *
  12. *      by Tim Krauskopf                                                    *
  13. *                                                                          *
  14. *      National Center for Supercomputing Applications                     *
  15. *      152 Computing Applications Building                                 *
  16. *      605 E. Springfield Ave.                                             *
  17. *      Champaign, IL  61820                                                *
  18. *                                                                          *
  19. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  20. *                                                                          *
  21. ****************************************************************************
  22. */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <Memory.h>
  27. #include <CType.h>
  28.  
  29. #include "protocol.h"
  30. #include "hostform.h"
  31. #include "tools.h"
  32. #include "macutil.h"
  33. #include "util.h"
  34. #include "user.h"
  35. #include "dlayer.h"
  36.  
  37. #define NUMSPECS 134    /* BYU 2.4.9 - add 2 new flags for linemode & eightbit */
  38.  
  39. char                             /* special function types */
  40.             *neterrstring();
  41. int32 time();                    /* don't forget this sucker! */
  42.  
  43. static struct machinfo *Smachlist,*Smptr;
  44. struct machinfo *Sns=NULL;
  45.  
  46. static unsigned char *Smachfile = {"config.tel"},
  47.             Sflags[NUMSPECS-95],    /* which parms we have or have not */
  48.             *Sspace;
  49.  
  50. struct config Scon = {
  51.         0,0,0,0,
  52.         0,
  53.         3,
  54.         127,0,0,1,
  55.         "",
  56.         7,1,0x70,
  57.         "atalk",
  58.         "ega",
  59.         0,        /* BYU 2.4.9 - BIOS anyone? */
  60.         1,        /* BYU 2.4.9 - enable tek graphics */
  61.         0,        /* BYU 2.4.9 - disable ftp */
  62.         1,        /* BYU 2.4.9 - enable rcp */
  63.         0,        /* BYU 2.4.9 - no command keys */
  64.         "DEC-VT100",
  65.         "*",
  66.         NULL,
  67.         NULL,
  68.         NULL,
  69.         NULL,
  70.         NULL,
  71.         NULL,
  72.         1,
  73.         4,
  74.         3,
  75.         -1,
  76.         120,
  77.         0x0d000,
  78.         0x0300,
  79.         0
  80. };
  81.  
  82. int
  83. Sxxnf[3] = NFDEF,
  84. Sxxnb[3] = NBDEF,
  85. Sxxbf[3] = BFDEF,
  86. Sxxbb[3] = BBDEF,
  87. Sxxuf[3] = UFDEF,
  88. Sxxub[3] = UBDEF;
  89.  
  90. static int
  91.         mno=0,                    /* how many machines in host file */
  92.         lineno,                    /* line number in hosts file */
  93.         position,                /* position for scanning string */
  94.         constate,                /* state for config file parser */
  95.         inquote;                /* flag, inside quotes now */
  96.  
  97. int TekFound=0;
  98.  
  99. /*
  100. *   States for config file reading state machine.
  101. *   One for each type of keyword and some for controlling.
  102. */
  103.  
  104. #define    CONNAME    101
  105. #define CONHOST    102
  106. #define CONIP    103
  107. #define CONGATE    104
  108. #define CONCOLOR 105
  109. #define CONBKSP    106
  110. #define CONBKSC    107
  111. #define CONRETR    108
  112. #define CONWIND    109
  113. #define CONSEG    110
  114. #define CONMTU    111
  115. #define CONNS    112
  116. #define CONTO    113
  117. #define CONCRMAP 114
  118. #define CONDUP  115
  119. #define CONWRAP 116
  120. #define CONWIDE 117
  121. #define CONFONT 118
  122. #define CONFSIZE 119
  123. #define CONNF 120
  124. #define CONNB 121
  125. #define CONBF 122
  126. #define CONBB 123
  127. #define CONUF 124
  128. #define CONUB 125
  129. #define CONRF 126
  130. #define CONRB 127
  131. #define CONCLMODE 128
  132. #define CONPORT 129
  133. #define CONLINES 130
  134. #define CONLKEYS 131
  135. /*
  136. *  above this line are per machine entries, below are configuration entries
  137. */
  138. #define CONMYIP    132
  139. #define CONHPF  133
  140. #define CONPSF  134
  141. #define CONTEKF 135
  142. #define CONJTIME 136
  143. #define CONME    137
  144. #define CONCCOL    138
  145. #define CONHW    139
  146. #define CONADDR    140
  147. #define CONIOA    141
  148. #define CONDEF  142
  149. #define CONCKEYS 143
  150. #define CONINT    144
  151. #define CONBIOS    145
  152. #define CONTEK    146
  153. #define CONVIDEO    147
  154. #define CONFTP    148
  155. #define CONRCP    149
  156. #define CONPASS    150
  157. #define CONCAP    151
  158. #define CONTTYPE    152
  159. #define CONNSTYPE     153
  160. #define CONFROM    154
  161. #define CONARPTO 155
  162. #define CONZONE 156
  163. #define CONNDOM  157
  164. #define CONDOMTO 158
  165. #define CONBLOCK 159
  166. #define    CONMASK    160
  167. #define CONTEKT    161            /* BYU 2.4.9 - corresponds to offset 32 in Sflags[] */
  168. #define CONLINEMODE 162        /* BYU 2.4.9 - corresponds to offset 33 in Sflags[] */
  169. #define CONEIGHTBIT 163        /* BYU 2.4.9 - corresponds to offset 34 in Sflags[] */
  170.  
  171. char *Skeyw[] = {
  172.         "",    
  173.         "name",                            /* name of session */
  174.         "host",                            /* name of host */
  175.         "hostip",                        /* IP number */
  176.         "gateway",                        /* gateway level */
  177.         "color",                        /* color code  ==5== */
  178.         "erase",                        /* value to use for backspace */
  179.         "scrollback",                    /* how many lines to backscroll */
  180.         "retrans",                        /* initial retrans time */
  181.         "rwin",                            /* window to allow for this host */
  182.         "maxseg",                        /* maximum transfer size (in) ==10== */
  183.         "mtu",                            /* transfer unit (out) */
  184.         "nameserver",                    /* name server level */
  185.         "contime",                        /* timeout for opening connection */
  186.         "crmap",                        /* map for Berkeley 4.3 compatibility */
  187.         "duplex",                        /* half duplex for IBM machines */
  188.         "vtwrap",                        /* should VT wrap? */
  189.         "vtwidth",                        /* width of VT100 screen */
  190.         "font",                            /* font to use, when given a choice */
  191.         "fsize",                        /* font size, in points */
  192.         "nfcolor",                        /* normal foreground color */
  193.         "nbcolor",                        /* normal background color */
  194.         "bfcolor",                        /* blink foreground color */
  195.         "bbcolor",                        /* blink background color */
  196.         "ufcolor",                        /* underline foreground color */
  197.         "ubcolor",                        /* underline background color */
  198.         "rfcolor",                        /* reverse foreground color */
  199.         "rbcolor",                        /* reverse background color */
  200.         "clearsave",                    /* clear screen saves lines */
  201.         "port",                            /* TCP port to go for */
  202.         "vtlines",                        /* number of lines for the VT100 window */
  203.         "localkeys",                    /* keys to use for int,susp,resume */
  204. /*
  205. *  following are one-time entries, above are part of the data structure
  206. */
  207.         "myip",                            /* local machine's IP # */
  208.         "hpfile",                        /* HPGL output file */
  209.         "psfile",                        /* postscript output file */
  210.         "tekfile",                        /* tektronix output file */
  211.         "timeslice",                    /* timer slice for multi-tasking */
  212.         "myname",                        /* identifying info ==15==*/
  213.         "concolor",                        /* console colors */
  214.         "hardware",                        /* network hardware */
  215.         "address",                        /* Address of hardware */
  216.         "ioaddr",                        /* ioaddress of hardware */
  217.         "domain",                        /* default domain for lookup */
  218.         "commandkeys",                    /* use command keys on mac */
  219.         "interrupt",                    /* interrupt request 3 or 5 */
  220.         "bios",                            /* use BIOS screen */
  221.         "tek",                            /* tektronix graphics ==20==*/
  222.         "video",                        /* type of video hardware */
  223.         "ftp",                            /* enable ftp? */
  224.         "rcp",                            /* enable rcp? */
  225.         "passfile",                        /* password file name */
  226.         "capfile",                        /* capture file name */
  227.         "termtype",                        /* terminal type */
  228.         "nameservertype",                /* nameserver type */
  229.         "copyfrom",                        /* copy from another machine */
  230.         "arptime",                        /* time-out for ARPs */
  231.         "zone",                            /* NBP zone for Macs */
  232.         "domainretry",                    /* # of retries */
  233.         "domaintime",                    /* time-out for DOMAIN */
  234.         "block",                        /* blocking for network update */
  235.         "netmask",                        /* subnetting mask */
  236.         "tektype",                        /* the TEK emulation:0 for 4014, 1 for 4105 */
  237.         "linemode",                        /* enable line mode? */        /* BYU 2.4.9 */
  238.         "eightbit",                        /* display 8 bit font */    /* BYU 2.4.9 */
  239.         ""
  240.     };
  241.  
  242.  
  243.  
  244. /************************************************************************/
  245. /*  Sgetconfig
  246. *   copy the configuration information into the user's data structure
  247. *   directly.  The user can do with it what he feels like.
  248. */
  249. void Sgetconfig
  250.   (
  251.     struct config *cp
  252.   )
  253.     {
  254.  
  255.     movenbytes(cp,&Scon,sizeof(struct config));
  256. }
  257.  
  258. /************************************************************************/
  259. /*  Serrline
  260. *   prints the line number of the host file error and posts the event
  261. *   for the line number error and posts the hosts file error.
  262. */
  263.  
  264. void Serrline
  265.   (
  266.     int n
  267.   )
  268.     {
  269.     char *p;
  270.  
  271.     p = neterrstring(-1);
  272.     sprintf(p,"Config file: error in line %4d",lineno+1);
  273.     netposterr(-1);
  274.  
  275.     netposterr(n);
  276. }
  277.  
  278. /**************************************************************************/
  279. /*  Sissep
  280. *   is the character a valid separator for the hosts file?
  281. *   separators are white space, special chars and :;=
  282. *
  283. */
  284. int Sissep
  285.   (
  286.     int c
  287.   )
  288.     {
  289.     if (c < 33)
  290.         return(1);
  291.     if (c == ':' || c == ';' || c == '=')
  292.         return(1);
  293.     return(0);
  294. }
  295.  
  296. /************************************************************************/
  297. /*  ncstrcmp
  298. *   No case string compare.
  299. *   Only returns 0=match, 1=no match, does not compare greater or less
  300. *   There is a tiny bit of overlap with the | 32 trick, but shouldn't be
  301. *   a problem.  It causes some different symbols to match.
  302. */
  303. ncstrcmp(sa,sb)
  304.     char *sa,*sb;
  305.     {
  306.  
  307.     while (*sa && *sa < 33)        /* don't compare leading spaces */
  308.         sa++;
  309.     while (*sb && *sb < 33)
  310.         sb++;
  311.  
  312.     while (*sa && *sb) {
  313.         if ((*sa != *sb) && ((*sa | 32) != (*sb | 32)))
  314.             return(1);
  315.         sa++;sb++;
  316.     }
  317.     if (!*sa && !*sb)        /* if both at end of string */
  318.         return(0);
  319.     else
  320.         return(1);
  321. }
  322.  
  323. struct machinfo 
  324. *Shostlook(hname)
  325.     char *hname;
  326.     {
  327.     struct machinfo *m;
  328.     m = Smachlist;
  329.     while (m != NULL) {
  330.  
  331.         if (m->sname && !ncstrcmp(hname,m->sname)) 
  332.             return(m);
  333.  
  334.         m = m->next;
  335.     }
  336.  
  337.     m = Smachlist;
  338.     while (m != NULL) {
  339.         if (m->hname && !ncstrcmp(hname,m->hname))
  340.             return(m);
  341.  
  342.         m = m->next;
  343.     }
  344.  
  345.     return(NULL);
  346.  
  347. }
  348.  
  349. /************************************************************************/
  350. /*  Scopyfrom
  351. *   Look at the Sflags array to determine which elements to copy from
  352. *   a previous machine's entries.  If a machine name as been given as
  353. *   "default", the state machine will fill in the fields from that
  354. *   machine's entries.
  355. *
  356. *   If the machine name to copyfrom is not present in the list, set the
  357. *   program default values for each field.
  358. */
  359. void Scopyfrom
  360.   (
  361.     char *s
  362.   )
  363.     {
  364.     struct machinfo *m;
  365.     int i,j;
  366.  
  367.     m = Shostlook(s);            /* search list */
  368.  
  369.     for (i=3; i <= NUMSPECS-100; i++)         /* through list of parms */
  370.         if (!Sflags[i]) {
  371.             j=i;
  372.             if (i==32) j=61;
  373.             else if (i==33) j=62;            /* BYU 2.4.9 */
  374.             else if (i==34) j=63;            /* BYU 2.4.9 */
  375.             if (m) switch (100+j) {
  376.                 case CONHOST:
  377.                     Smptr->hname = m->hname;
  378.                     break;
  379.                 case CONIP:
  380.                     movebytes(Smptr->hostip,m->hostip,4);
  381.                     Smptr->mstat = m->mstat;
  382.                     break;
  383.                 case CONGATE:            /* gateways cannot be copied from */
  384.                     Smptr->gateway = 0;
  385.                     break;
  386.                 case CONNS:                    /* can't copy nameservers either */
  387.                     Smptr->nameserv = 0;
  388.                     break;
  389.  
  390.                 case CONBKSP:
  391.                     Smptr->bksp = m->bksp;
  392.                     break;
  393.                 case CONBKSC:
  394.                     Smptr->bkscroll = m->bkscroll;
  395.                     break;
  396.                 case CONCLMODE:
  397.                     Smptr->clearsave = m->clearsave;
  398.                     break;
  399.                 case CONLINEMODE:                        /* BYU 2.4.9 */
  400.                     Smptr->linemode = m->linemode;        /* BYU 2.4.9 */
  401.                     break;                                /* BYU 2.4.9 */
  402.                 case CONEIGHTBIT:                        /* BYU 2.4.9 */
  403.                     Smptr->eightbit = m->eightbit;        /* BYU 2.4.9 */
  404.                     break;                                /* BYU 2.4.9 */
  405.                 case CONRETR:
  406.                     Smptr->retrans = m->retrans;
  407.                     break;
  408.                 case CONWIND:
  409.                     Smptr->window = m->window;
  410.                     break;
  411.                 case CONSEG:
  412.                     Smptr->maxseg = m->maxseg;
  413.                     break;
  414.                 case CONMTU:
  415.                     Smptr->mtu = m->mtu;
  416.                     break;
  417.  
  418.                 case CONTO:
  419.                     Smptr->conto = m->conto;
  420.                     break;
  421.                 case CONCRMAP:
  422.                     Smptr->crmap = m->crmap;
  423.                     break;
  424.                 case CONDUP:
  425.                     Smptr->halfdup = m->halfdup;
  426.                     break;
  427.                 case CONTEKT:
  428.                     Smptr->tektype = m->tektype;
  429.                     break;
  430.                 case CONWRAP:
  431.                     Smptr->vtwrap = m->vtwrap;
  432.                     break;
  433.                 case CONWIDE:
  434.                     Smptr->vtwidth = m->vtwidth;
  435.                     break;
  436.                 case CONLINES:
  437.                     Smptr->nlines = m->nlines;
  438.                     break;
  439.  
  440.                 case CONNF:
  441.                     movebytes(Smptr->nfcolor,m->nfcolor,3*sizeof(int));
  442.                     break;
  443.                 case CONNB:
  444.                     movebytes(Smptr->nbcolor, m->nbcolor,3*sizeof(int));
  445.                     break;
  446.                 case CONBF:
  447.                     movebytes(Smptr->bfcolor,m->bfcolor,3*sizeof(int));
  448.                     break;
  449.                 case CONBB:
  450.                     movebytes(Smptr->bbcolor,m->bbcolor,3*sizeof(int));
  451.                     break;
  452.                 case CONUF:
  453.                     movebytes(Smptr->ufcolor,m->ufcolor,3*sizeof(int));
  454.                     break;
  455.                 case CONUB:
  456.                     movebytes(Smptr->ubcolor,m->ubcolor,3*sizeof(int));
  457.                     break;
  458.  
  459.                 case CONLKEYS:
  460.                     Smptr->ckey = m->ckey;
  461.                     Smptr->skey = m->skey;
  462.                     Smptr->qkey = m->qkey;
  463.                     break;
  464.  
  465.                 case CONFONT:
  466.                     Smptr->font = m->font;
  467.                     break;
  468.                 case CONFSIZE:
  469.                     Smptr->fsize = m->fsize;
  470.                     break;
  471.                 case CONPORT:
  472.                     Smptr->port = m->port;
  473.                     break;
  474.  
  475.                 default:
  476.                     break;
  477.             }
  478.             else
  479.             switch (100+j) {        /* m=NULL, install default values */
  480.                 case CONHOST:
  481.                     Smptr->hname = NULL;
  482.                     break;
  483.                 case CONIP:
  484.                     Smptr->mstat = NOIP;
  485.                     break;
  486.                 case CONGATE:            /* gateways cannot be copied from */
  487.                     Smptr->gateway = 0;
  488.                     break;
  489.                 case CONBKSP:
  490.                     Smptr->bksp = 127;
  491.                     break;
  492.                 case CONBKSC:
  493.                     Smptr->bkscroll = 0;
  494.                     break;
  495.                 case CONCLMODE:
  496.                     Smptr->clearsave = 1;
  497.                     break;
  498.                 case CONLINEMODE:                        /* BYU 2.4.9 */
  499.                     Smptr->linemode = 1;                /* BYU 2.4.9 */
  500.                     break;                                /* BYU 2.4.9 */
  501.                 case CONEIGHTBIT:                        /* BYU 2.4.9 */
  502.                     Smptr->eightbit = 1;                /* BYU 2.4.9 */
  503.                     break;                                /* BYU 2.4.9 */
  504.                 case CONRETR:
  505.                     Smptr->retrans = SMINRTO;
  506.                     break;
  507.                 case CONWIND:
  508. #ifdef MAC
  509.                     Smptr->window = 512;
  510. #else
  511.                     Smptr->window = DEFWINDOW;
  512. #endif
  513.                     break;
  514.                 case CONSEG:
  515. #ifdef MAC
  516.                     Smptr->maxseg = 512;
  517. #else
  518.                     Smptr->maxseg = DEFSEG;
  519. #endif
  520.                     break;
  521.                 case CONMTU:
  522. #ifdef MAC
  523.                     Smptr->mtu = 512;
  524. #else
  525.                     Smptr->mtu = TSENDSIZE;
  526. #endif
  527.                     break;
  528.  
  529.                 case CONNS:                    /* can't copy nameservers either */
  530.                     Smptr->nameserv = 0;
  531.                     break;
  532.         
  533.                 case CONTO:
  534.                     Smptr->conto = CONNWAITTIME;
  535.                     break;
  536.  
  537.                 case CONCRMAP:
  538.                     Smptr->crmap = 10;
  539.                     break;
  540.  
  541.                 case CONDUP:
  542.                     Smptr->halfdup = 0;
  543.                     break;
  544.                 case CONWRAP:
  545.                     Smptr->vtwrap = 0;
  546.                     break;
  547.                 case CONWIDE:
  548.                     Smptr->vtwidth = 80;
  549.                     break;
  550.                 case CONTEKT:
  551.                     Smptr->tektype = 0;
  552.                     break;
  553.                 case CONLINES:
  554.                     Smptr->nlines = 24;        /* overall default to 24 lines */
  555.                     break;
  556.  
  557.                 case CONNF:
  558.                     movebytes(Smptr->nfcolor,Sxxnf,3*sizeof(int));
  559.                     break;
  560.                 case CONNB:
  561.                     movebytes(Smptr->nbcolor,Sxxnb,3*sizeof(int));
  562.                     break;
  563.                 case CONBF:
  564.                     movebytes(Smptr->bfcolor,Sxxbf,3*sizeof(int));
  565.                     break;
  566.                 case CONBB:
  567.                     movebytes(Smptr->bbcolor,Sxxbb,3*sizeof(int));
  568.                     break;
  569.                 case CONUF:
  570.                     movebytes(Smptr->ufcolor,Sxxuf,3*sizeof(int));
  571.                     break;
  572.                 case CONUB:
  573.                     movebytes(Smptr->ubcolor,Sxxub,3*sizeof(int));
  574.                     break;
  575.  
  576.                 case CONLKEYS:
  577.                     Smptr->ckey = 3;            /* Ctrl-C */
  578.                     Smptr->skey = 19;            /* Ctrl-S */
  579.                     Smptr->qkey = 17;            /* Ctrl-Q */
  580.                     break;
  581.  
  582.                 case CONFONT:
  583.                     Smptr->font = "Monaco";
  584.                     break;
  585.                 case CONFSIZE:
  586.                     Smptr->fsize = 9;
  587.                     break;
  588.                 case CONPORT:
  589.                     Smptr->port = 23;            /* the telnet port */
  590.                     break;
  591.  
  592.                 default:
  593.                     break;
  594.             }
  595.         }
  596.  
  597.     Sflags[0] = 1;                    /* set that this machine was copied */
  598. } /* Scopyfrom */
  599.  
  600. /************************************************************************/
  601. /*  Sconfile
  602. *   take the characters read from the file and parse them for keywords
  603. *   which require configuration action.
  604. */
  605. int Sconfile
  606.   (
  607.     char *s
  608.   )
  609.     {
  610.     int i,a,b,c,d;
  611.  
  612.     switch (constate) {
  613.         case 0:                                /* lookup keyword */
  614.             if (!(*s))                        /* empty token */
  615.                 return(0);
  616.  
  617.  
  618.             for (i=1; *Skeyw[i] && ncstrcmp(Skeyw[i],s); i++)
  619.                     ;
  620.             if (!(*Skeyw[i])) {            /* not in list */
  621.                 Serrline(902);
  622.                 return(0);                /* don't die - helps backward compatibility */
  623.             }
  624.             constate = 100+i;    /* change to state for keyword */
  625. /*
  626. *  check if this is a machine specific parm without a machine to
  627. *  give it to.  "name" being the only machine specific parm allowed, of course
  628. */
  629.             if (Smptr == NULL && constate > 101 && constate <= NUMSPECS) {
  630.                 Serrline(905);
  631.                 return(1);
  632.             }
  633.             break;
  634.  
  635.         case CONNAME:
  636. /*
  637. *  allocate space for upcoming parameters
  638. */
  639.             if (Smachlist == NULL) {
  640.                 Smachlist = (struct machinfo *)NewPtr(sizeof(struct machinfo));
  641.                 Smptr = Smachlist;
  642.                 Smptr->sname = NULL;
  643.                 Smptr->hname = NULL;
  644.             }
  645.             else {
  646.                 if (!Sflags[0]) {
  647.                     if (ncstrcmp("default",Smptr->sname))
  648.                         Scopyfrom("default");
  649.                     else
  650.                         Scopyfrom("==");    /* to make sure 'default' gets set */
  651.                 }
  652.                 Smptr->next = 
  653.                     (struct machinfo *)NewPtr(sizeof(struct machinfo));
  654.                 Smptr = Smptr->next;
  655.             }
  656.             Smptr->next = NULL;
  657.             Smptr->hname = NULL;                /* guarantee to be null */
  658.             (Ptr) Smptr->sname = NewPtr(position);    /* size of name string */
  659.             strcpy(Smptr->sname,s);                /* keep name field */
  660.             constate = 0;                        /* back to new keyword */
  661.             for (i=0; i<NUMSPECS-99; i++)
  662.                 Sflags[i] = 0;                    /* we have no parms */
  663.             Smptr->mno = ++mno;                    /* new machine number */
  664.             break;
  665.  
  666.         case CONHOST:                            /* also a name */
  667.             (Ptr) Smptr->hname = NewPtr(position);
  668.             strcpy(Smptr->hname,s);
  669.             constate = 0;
  670.             Sflags[CONHOST-100] = 1;
  671.             break;
  672.  
  673.         case CONIP:                                /* IP number for host */
  674.             if ( 4 != sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) {
  675.                 Serrline(906);
  676.                 return(3);
  677.             }
  678.             Smptr->hostip[0]=a; Smptr->hostip[1] =b;     /* keep number */
  679.             Smptr->hostip[2]=c; Smptr->hostip[3] =d;
  680.             Smptr->mstat = HFILE;
  681.             constate = 0;
  682.             Sflags[CONIP-100] = 1;
  683.             break;
  684.  
  685.         case CONGATE:
  686.             Smptr->gateway = atoi(s);            /* gateway level */
  687.             constate = 0;
  688.             Sflags[CONGATE-100] = 1;
  689.             break;
  690.  
  691.         case CONCOLOR:                    /* support old format */
  692.             Smptr->nfcolor[0] = s[1]-48;
  693.             Smptr->nbcolor[0] = s[0]-48;
  694.             Smptr->bfcolor[0] = s[5]-48;
  695.             Smptr->bbcolor[0] = s[4]-48;
  696.             Smptr->ufcolor[0] = s[3]-48;
  697.             Smptr->ubcolor[0] = s[2]-48;
  698.             constate = 0;
  699.             Sflags[CONNF-100] = 1;        /* sets them all at one shot */
  700.             Sflags[CONNB-100] = 1;
  701.             Sflags[CONBF-100] = 1;
  702.             Sflags[CONBB-100] = 1;
  703.             Sflags[CONUF-100] = 1;
  704.             Sflags[CONUB-100] = 1;
  705.             break;
  706.  
  707.         case CONNF:                        /* foreground normal color */
  708.             if (Scolorset(Smptr->nfcolor,s))
  709.                 Sflags[CONNF-100] = 1;
  710.             constate = 0;
  711.             break;
  712.         case CONNB:                        /* background normal color */
  713.             if (Scolorset(Smptr->nbcolor,s))
  714.                 Sflags[CONNB-100] = 1;
  715.             constate = 0;
  716.             break;
  717.         case CONRF:
  718.         case CONBF:                        /* blink foreg color */
  719.             if (Scolorset(Smptr->bfcolor,s))
  720.                 Sflags[CONBF-100] = 1;    /* in copyfrom, r's are really b's */
  721.             constate = 0;
  722.             break;
  723.         case CONRB:
  724.         case CONBB:                        /* blink bg color */
  725.             if (Scolorset(Smptr->bbcolor,s))
  726.                 Sflags[CONBB-100] = 1;
  727.             constate = 0;
  728.             break;
  729.         case CONUF:                        /* foreground underline color */
  730.             if (Scolorset(Smptr->ufcolor,s))
  731.                 Sflags[CONUF-100] = 1;
  732.             constate = 0;
  733.             break;
  734.         case CONUB:                        /* bg underline color */
  735.             if (Scolorset(Smptr->ubcolor,s))
  736.                 Sflags[CONUB-100] = 1;
  737.             constate = 0;
  738.             break;
  739.  
  740.         case CONLKEYS:                    /* local key bindings */
  741.             { int a,b,c;
  742.                 if (3!=sscanf(s,"{%d,%d,%d}", &a, &b, &c))
  743.                     Smptr->ckey = Smptr->skey = Smptr->qkey = 0;    /* default = off */
  744.                 else {
  745.                     Smptr->ckey = a;
  746.                     Smptr->skey = b;
  747.                     Smptr->qkey = c;
  748.                 }
  749.             }
  750.             Sflags[CONLKEYS-100] = 1;
  751.             constate = 0;
  752.             break;
  753.  
  754.         case CONBKSP:
  755.             if (!ncstrcmp(s,"backspace"))
  756.                 Smptr->bksp = 8;
  757.             else
  758.                 Smptr->bksp = 127;
  759.             constate = 0;
  760.             Sflags[CONBKSP-100] = 1;
  761.             break;
  762.  
  763.         case CONBKSC:
  764.             Smptr->bkscroll = atoi(s);
  765.             constate = 0;
  766.             Sflags[CONBKSC-100] = 1;
  767.             break;
  768.  
  769.         case CONRETR:
  770.             Smptr->retrans = atoi(s);
  771.             constate = 0;
  772.             Sflags[CONRETR-100] = 1;
  773.             break;
  774.  
  775.         case CONWIND:
  776.             Smptr->window = atoi(s);
  777.             constate = 0;
  778.             Sflags[CONWIND-100] = 1;
  779.             break;
  780.  
  781.         case CONSEG:
  782.             Smptr->maxseg = atoi(s);
  783.             constate = 0;
  784.             Sflags[CONSEG-100] = 1;
  785.             break;
  786.  
  787.         case CONMTU:
  788.             Smptr->mtu = atoi(s);
  789.             constate = 0;
  790.             Sflags[CONMTU-100] = 1;
  791.             break;
  792.  
  793.         case CONNS:
  794.             Smptr->nameserv = atoi(s);
  795.             if (!Sns || (Sns->nameserv > Smptr->nameserv))    /* keep NS */
  796.                 Sns = Smptr;
  797.             constate = 0;
  798.             Sflags[CONNS-100] = 1;
  799.             break;
  800.  
  801.         case CONTO:
  802.             i = atoi(s);
  803.             if (i > 2) {
  804.                 Smptr->conto = i;
  805.                 Sflags[CONTO-100] = 1;
  806.             }
  807.             constate = 0;
  808.             break;
  809.  
  810.         case CONCRMAP:
  811.             if (!ncstrcmp(s,"4.3BSDCRNUL")) 
  812.                 Smptr->crmap = 0;
  813.             else
  814.                 Smptr->crmap = 10;
  815.             Sflags[CONCRMAP-100] = 1;
  816.             constate = 0;
  817.             break;
  818.  
  819.         case CONDUP:
  820.             if (!ncstrcmp(s,"half")) {
  821.                 Smptr->halfdup = 1;
  822.                 Sflags[CONDUP-100] = 1;
  823.             }
  824.             constate = 0;
  825.             break;
  826.  
  827.         case CONWRAP:
  828.             if ('Y' == toupper(s[0])) 
  829.                 Smptr->vtwrap = 1;
  830.             else
  831.                 Smptr->vtwrap = 0;
  832.             Sflags[CONWRAP-100] = 1;
  833.             constate = 0;
  834.             break;
  835.  
  836.         case CONCLMODE:
  837.             if ('N' == toupper(s[0])) 
  838.                 Smptr->clearsave = 0;
  839.             else
  840.                 Smptr->clearsave = 1;
  841.             Sflags[CONCLMODE-100] = 1;
  842.             constate = 0;
  843.             break;
  844.  
  845.         case CONFONT:
  846.             (Ptr) Smptr->font = NewPtr(position);
  847.             strcpy(Smptr->font,s);
  848.             Sflags[CONFONT-100] = 1;
  849.             constate = 0;
  850.             break;
  851.  
  852.         case CONFSIZE:
  853.             Smptr->fsize = atoi(s);
  854.             Sflags[CONFSIZE-100] = 1;
  855.             constate = 0;
  856.             break;
  857.  
  858.         case CONWIDE:
  859.             if (132 == atoi(s)) 
  860.                 Smptr->vtwidth = 132;
  861.             else
  862.                 Smptr->vtwidth = 80;
  863.  
  864.             Sflags[CONWIDE-100] = 1;
  865.             constate = 0;
  866.             break;
  867.  
  868.         case CONTEKT:
  869.             if (0 == atoi(s)) 
  870.                 Smptr->tektype = 0;
  871.             else
  872.                 Smptr->tektype = 1;
  873.  
  874.             Sflags[32] = 1;
  875.             TekFound=1;
  876.             constate = 0;
  877.             break;
  878.  
  879.         case CONLINES:
  880.             i = atoi(s);
  881.             if (i > 6 && i < 100)
  882.                 Smptr->nlines = i;
  883.             else
  884.                 Smptr->nlines = 24;            /* default is 24 lines */
  885.             Sflags[CONLINES-100] = 1;
  886.             constate = 0;
  887.             break;
  888.  
  889.         case CONPORT:                        /* File name for Tek dump */
  890.             i = atoi(s);
  891.             if (i < 1)
  892.                 i = 23;
  893.             Smptr->port = i;
  894.             Sflags[CONPORT-100] = 1;
  895.             constate = 0;
  896.             break;
  897.  
  898. /*
  899. *  now the one-time entries
  900. *  Generally this information goes into the "Scon" structure for later
  901. *  retrieval by other routines.
  902. *
  903. */
  904. #ifdef PC
  905.         case CONMASK:
  906.             if ( 4 != sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) {
  907.                 Serrline(907);
  908.                 return(3);
  909.             }
  910.             Scon.netmask[0]=a; Scon.netmask[1] =b;     
  911.             Scon.netmask[2]=c; Scon.netmask[3] =d;
  912.             Scon.havemask=1;
  913.             constate = 0;
  914.             break;
  915.  
  916.         case CONMYIP:
  917.             constate = 0;
  918.             if (!ncstrcmp(s,"rarp")) {
  919.                 movebytes(Scon.myipnum,s,4);
  920.                 netsetip("RARP");
  921.                 break;
  922.             }
  923.             if ( 4 != sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) {
  924.                 Serrline(908);
  925.                 return(3);
  926.             }
  927.             Scon.myipnum[0]=a; Scon.myipnum[1] =b;     /* put number back in s */
  928.             Scon.myipnum[2]=c; Scon.myipnum[3] =d;
  929.             netsetip(Scon.myipnum);        /* make permanent set */
  930.             break;
  931. #endif
  932.         case CONME:                /* what my name is  */
  933.             strncpy(Scon.me,s,30);
  934.             Scon.me[30] = '\0';
  935.             constate = 0;
  936.             break;
  937.  
  938.         case CONHW:                /* what hardware are we using? */
  939.             i = strlen(s);
  940.             if (i > 9) i = 9;
  941.             s[i] = '\0';
  942.             i--;
  943.             while (i--)
  944.                 s[i] = tolower(s[i]);
  945.             strcpy(Scon.hw,s);
  946.             constate = 0;
  947.             break;
  948.  
  949. #ifdef PC
  950.         case CONINT:            /* what IRQ to use */
  951.             sscanf(s,"%x",&i);
  952.             Scon.irqnum = i;
  953.             constate = 0;
  954.             break;
  955.  
  956.         case CONBIOS:
  957.             if (toupper(*s) == 'Y') {
  958.                 Scwritemode(0);
  959.                 Scon.bios = 1;
  960.             }
  961.             constate = 0;
  962.             break;
  963.  
  964.         case CONADDR:                /* segment address for board */
  965.             sscanf(s,"%x",&i);
  966.             Scon.address = i;
  967.             constate = 0;
  968.             break;
  969.  
  970.         case CONIOA:                /* io address for board */
  971.             sscanf(s,"%x",&i);
  972.             Scon.ioaddr = i;
  973.             constate = 0;
  974.             break;
  975. #endif
  976. #ifdef MAC
  977.         case CONCKEYS:
  978.             if (toupper(*s) == 'Y') {
  979.                 Scon.comkeys = 1;
  980.             }
  981.             constate = 0;
  982.             break;
  983.  
  984.         case CONZONE:
  985.             Scon.zone = NewPtr(position);    /* space for name */
  986.             strcpy(Scon.zone,s);            /* copy it in */
  987.             constate = 0;
  988.             break;
  989.  
  990.         case CONJTIME:                /* Time slice */
  991.             i = atoi(s);
  992.             if (i > 1)
  993.                 Scon.timesl = i;
  994.             constate = 0;
  995.             break;
  996. #endif        
  997.  
  998.         case CONTEK:
  999.             if (toupper(*s) == 'N') {
  1000.                 Stekmode(0);
  1001.                 Scon.tek = 0;
  1002.             }
  1003.             constate = 0;
  1004.             break;
  1005.  
  1006.         case CONVIDEO:
  1007.             i = strlen(s);
  1008.             if (i > 9) i = 9;
  1009.             s[i] = '\0';
  1010.             strcpy(Scon.video,s);
  1011.             i--;
  1012.             while (i--)
  1013.                 s[i] = tolower(s[i]);
  1014.             constate = 0;
  1015.             break;
  1016.  
  1017.         case CONTTYPE:
  1018.             (Ptr) Scon.termtype = NewPtr(position);
  1019.             strcpy(Scon.termtype,s);
  1020.             constate = 0;
  1021.             break;
  1022.  
  1023.         case CONCCOL:
  1024.             for (i=0; i<3; i++)
  1025.                 Scon.color[i] = ((s[i*2]-48)<<4) + (s[i*2+1]-48);
  1026.             constate = 0;
  1027.             break;
  1028.  
  1029.         case CONFTP:
  1030.             if (toupper(*s) == 'N') 
  1031.                 Scon.ftp = 0;    
  1032.             else                            /* BYU 2.4.10 */
  1033.                 Scon.ftp = 1;                /* BYU 2.4.10 */
  1034.             constate = 0;
  1035.             break;
  1036.  
  1037.         case CONRCP:
  1038.             if (toupper(*s) == 'N')
  1039.                 Scon.rcp = 0;
  1040.             constate = 0;
  1041.             break;
  1042.  
  1043.         case CONPASS:
  1044.             (Ptr) Scon.pass = NewPtr(position);    /* space for name */
  1045.             strcpy(Scon.pass,s);            /* copy it in */
  1046.             constate = 0;
  1047.             break;
  1048.  
  1049.         case CONDEF:                        /* default domain */
  1050.             (Ptr) Scon.defdom = NewPtr(position);    /* space for name */
  1051.             strcpy(Scon.defdom,s);            /* copy it in */
  1052.             constate = 0;
  1053.             break;
  1054.  
  1055.         case CONCAP:                        /* capture file name */
  1056.             Snewcap(s);
  1057.             constate = 0;
  1058.             break;
  1059.  
  1060.         case CONFROM:                        /* copy the rest from another */
  1061.                                             /* entry in the table */
  1062.             Scopyfrom(s);
  1063.             Sflags[0] = 1;                    /* indicate did copy from */
  1064.             constate = 0;
  1065.             break;
  1066.  
  1067.         case CONARPTO:                        /* need to lengthen arp time-out (secs) */
  1068.             i = atoi(s);
  1069.             if (i > 0)
  1070.                 netarptime(i);
  1071.             constate = 0;                    /* don't forget me! */
  1072.             break;
  1073.  
  1074.         case CONBLOCK:                        /* blocking factor for text */
  1075.             i = atoi(s);
  1076.             if (i > 4096) i = 4096;
  1077.             if (i > 0)
  1078.                 Scon.textblock = i;
  1079.             constate = 0;                    /* don't forget me! */
  1080.             break;
  1081.  
  1082.         case CONDOMTO:                        /* DOMAIN timeout value */
  1083.             i = atoi(s);
  1084.             if (i > 1)
  1085.                 Scon.domto = i;
  1086.             constate = 0;
  1087.             break;
  1088.  
  1089.         case CONNDOM:                        /* DOMAIN number of retries */
  1090.             i = atoi(s);
  1091.             if (i > 1)
  1092.                 Scon.ndom = i;
  1093.             constate = 0;
  1094.             break;
  1095.  
  1096.         case CONHPF:                /* File name for HP dump */
  1097.             Snewhpfile(s);
  1098.             constate = 0;
  1099.             break;
  1100.  
  1101.         case CONPSF:                /* File name for PS dump */
  1102.             Snewpsfile(s);
  1103.             constate = 0;
  1104.             break;
  1105.  
  1106.         case CONTEKF:                /* File name for Tek dump */
  1107.             Snewtekfile(s);
  1108.             constate = 0;
  1109.             break;
  1110.  
  1111.         case CONLINEMODE:                /* BYU 2.4.9 */
  1112.             if (toupper(*s) == 'N')     /* BYU 2.4.9 */
  1113.                 Smptr->linemode = 0;    /* BYU 2.4.9 */
  1114.             else                        /* BYU 2.4.9 */
  1115.                 Smptr->linemode = 1;    /* BYU 2.4.9 */
  1116.             Sflags[33] = 1;                /* BYU 2.4.9 */
  1117.             constate = 0;                /* BYU 2.4.9 */
  1118.             break;                        /* BYU 2.4.9 */
  1119.  
  1120.         case CONEIGHTBIT:                /* BYU 2.4.9 */
  1121.             if (toupper(*s) == 'N')     /* BYU 2.4.9 */
  1122.                 Smptr->eightbit = 0;    /* BYU 2.4.9 */
  1123.             else                        /* BYU 2.4.9 */
  1124.                 Smptr->eightbit = 1;    /* BYU 2.4.9 */
  1125.             Sflags[34] = 1;                /* BYU 2.4.9 */
  1126.             constate = 0;                /* BYU 2.4.9 */
  1127.             break;                        /* BYU 2.4.9 */
  1128.  
  1129.         default:
  1130.             constate = 0;
  1131.             break;
  1132.     }
  1133.  
  1134.     return(0);
  1135. } /* Sconfile */
  1136.  
  1137. /************************************************************************/
  1138. /* Scontoken
  1139. *  tokenize the strings which get passed to Sconfile.
  1140. *  Handles quotes and uses separators:  <33, ;:=
  1141. */
  1142. int Scontoken
  1143.   (
  1144.     int c
  1145.   )
  1146.     {
  1147.     int retval;
  1148.  
  1149.     if (c == EOF) {
  1150.         Sspace[position++] = '\0';
  1151.         Sconfile(Sspace);
  1152.         if (!Sflags[0]) {            /* make sure last entry gets copied */
  1153.             if (ncstrcmp("default",Smptr->sname))
  1154.                 Scopyfrom("default");
  1155.             else
  1156.                 Scopyfrom("==");
  1157.         }
  1158.         return(-1);
  1159.     }
  1160.  
  1161.     if (!position && Sissep(c))        /* skip over junk before token */
  1162.         return(0);
  1163.  
  1164.     if (inquote || !Sissep(c)) {
  1165.  
  1166.         if (position > 200) {
  1167.             Serrline(903);
  1168.             return(1);
  1169.         }
  1170. /*
  1171. *  check for quotes, a little mixed up here, could be reorganized
  1172. */
  1173.         if (c == '"' ) {
  1174.             if (!inquote) {            /* beginning of quotes */
  1175.                 inquote = 1;
  1176.                 return(0);
  1177.             }
  1178.             else
  1179.                 inquote = 0;        /* turn off flag and drop through */
  1180.  
  1181.         }
  1182.         else {                        
  1183.             if (c == '\n') {            /* check for EOL inside quotes */
  1184.                 Serrline(904);
  1185.                 return(1);
  1186.             }
  1187.             Sspace[position++] = c;    /* include in current string */
  1188.             return(0);
  1189.         }
  1190.                 
  1191.     }
  1192.  
  1193.     Sspace[position++] = '\0';
  1194.  
  1195.     retval = Sconfile(Sspace);            /* pass the token along */
  1196.  
  1197.     position = 0;
  1198.     inquote = 0;
  1199.     Sspace[0] = '\0';
  1200.  
  1201.     return(retval);
  1202. }
  1203.  
  1204. /************************************************************************/
  1205. /*  Sreadhosts
  1206. *   read in the hosts file into our in-memory data structure.
  1207. *   Handle everything by keyword, see docs for specifications about file.
  1208. */
  1209. int Sreadhosts
  1210.   (
  1211.     void
  1212.   )
  1213.     {
  1214.     FILE *fp;
  1215.     int c,retval;
  1216.  
  1217.     Smachlist = Smptr = NULL;
  1218.     mno = 0;
  1219.  
  1220.     Sspace = NewPtr(256);                /* get room for gathering stuff */
  1221.     if (Sspace == NULL) {
  1222.         Serrline(901);
  1223.         return(1);
  1224.     }
  1225.     position = constate = inquote = lineno = 0;   /* state vars */    
  1226.  
  1227.     if (NULL == (fp = fopen(Smachfile,"r")))    /* BYU - 9 lines from Scott@NCSA. */
  1228.         {
  1229.         sysdir();
  1230.         if (NULL == (fp = fopen(Smachfile,"r"))) 
  1231.             {        
  1232.             Serrline(900);
  1233.             return (1);
  1234.             }
  1235.         setmydir();        /* BYU - get back to default dir */
  1236.         }
  1237.  
  1238.     retval = 0;
  1239.     while (!retval) {
  1240.         c = fgetc(fp);
  1241.         if (c == '#' && !inquote) {
  1242.             while (c != EOF && c != '\n' && c != '\r')        /* skip to EOL */
  1243.                 c = fgetc(fp);
  1244.         }
  1245.         if (c == '\n' || c == '\r')
  1246.             lineno++;
  1247.         retval = Scontoken(c);
  1248.     }
  1249.  
  1250.     fclose(fp);
  1251.     DisposPtr(Sspace);
  1252.  
  1253.     Smadd("default");                /* make sure name is in list */
  1254.  
  1255.     if (retval == EOF)                /* EOF is normal end */
  1256.         return(0);
  1257.     else
  1258.         return(retval);
  1259.  
  1260. }
  1261.  
  1262. /************************************************************************/
  1263. /*  Smadd
  1264. *   Add a machine to the list. Increments machine number of machine.
  1265. *   Puts in parameters copied from the "default" entry.
  1266. *
  1267. */
  1268. struct machinfo 
  1269. *Smadd(mname)
  1270.     char *mname;
  1271.     {
  1272.     int i;
  1273.     struct machinfo *m;
  1274. /*
  1275. *  First, do we have the name already?
  1276. */
  1277.     m = Shostlook(mname);
  1278.     if (m)
  1279.         return(m);
  1280. /*
  1281. *   Don't have name, add another record
  1282. */
  1283.     Smptr = (struct machinfo *)NewPtr(sizeof(struct machinfo));
  1284.     if (Smptr == NULL)
  1285.         return(NULL);
  1286.  
  1287.     for (i=0; i < NUMSPECS-99; i++)
  1288.         Sflags[i] = 0;                    /* we have no parms */
  1289.     Scopyfrom("default");
  1290.  
  1291.     Smptr->sname = NULL;
  1292.     (Ptr) Smptr->hname = NewPtr(strlen(mname)+1);
  1293.     if (Smptr->hname)
  1294.         strcpy(Smptr->hname,mname);        /* copy in name of machine */
  1295.     Smptr->mno = ++mno;
  1296.     Smptr->mstat = NOIP;
  1297.  
  1298.     Smptr->next = Smachlist;            /* add to front of machlist */
  1299.     Smachlist = Smptr;
  1300.  
  1301.     return(Smptr);
  1302.  
  1303. }
  1304.  
  1305.  
  1306. /************************************************************************/
  1307. /* Shostfile
  1308. *   if the user wants to change the host file name from 'config.tel' to
  1309. *   something else.
  1310. */
  1311. void Shostfile
  1312.   (
  1313.     char *ptr
  1314.   )
  1315.   {
  1316.     Smachfile = ptr;    
  1317. /*
  1318. *  note that the area with the file name must stay allocated for
  1319. *  later reference, typically it is in some argv[] parm.
  1320. */
  1321.   }
  1322.  
  1323. /************************************************************************/
  1324. /*  get host by name
  1325. *   Given the name of a host machine, search our database to see if we
  1326. *   have that host ip number.  Search first the name field, and then the
  1327. *   hostname field.
  1328. *   Returns the pointer to the correct record, or pointer to the default
  1329. *   record if the number is not available
  1330. */
  1331. struct machinfo *Sgethost(machine)
  1332.     char *machine;
  1333.     {
  1334.     int i,j,k,l;
  1335.     unsigned char ipto[4],myipnum[4],xmask[4];
  1336.     unsigned long hnum;
  1337.     struct machinfo *m;
  1338.  
  1339.     m = NULL;
  1340. /*
  1341. *  First, check for the pound sign character which means we should use
  1342. *  the current netmask to build an IP number for the local network.
  1343. *  Take the host number, install it in the ipto[] array.  Then mask
  1344. *  in my IP number's network portion to build the final IP address.
  1345. */
  1346.  
  1347.     if ('#' == machine[0]) {        /* on my local network */
  1348.         netgetip(myipnum);
  1349.         netgetmask(xmask);            /* mask of network portion of IP # */
  1350.  
  1351.         sscanf(&machine[1],"%ld",&hnum);/* host number for local network */
  1352.         for (i=3; i >= 0; i--) {
  1353.             ipto[i] = hnum & 255L;    /* take off a byte */
  1354.             hnum >>= 8;                /* shift it over */
  1355.         }
  1356.  
  1357.         for (i=0; i < 4; i++) 
  1358.             ipto[i] |= (myipnum[i] & xmask[i]);        /* mask new one in */
  1359.  
  1360.     }
  1361. /*
  1362. *  next, is it an IP number?  We take it if the number is in four
  1363. *  parts, separated by periods.
  1364. */
  1365.     else 
  1366.     if (4 == sscanf(machine,"%d.%d.%d.%d",&i,&j,&k,&l)) {    /* given ip num */
  1367.         ipto[0] = i;
  1368.         ipto[1] = j;
  1369.         ipto[2] = k;
  1370.         ipto[3] = l;
  1371.     }
  1372. /*
  1373. *  lastly, it must be a name, first check the local host table
  1374. *  A first number of 127 means that it doesn't have an IP number, but
  1375. *  is in the table (strange occurrence)
  1376. */
  1377.     else {                                    /* look it up */
  1378.  
  1379.         m = Shostlook(machine);
  1380.         if (m == NULL) {
  1381.             netposterr(805);                /* informative */
  1382.             return(NULL);
  1383.         } 
  1384.         if (m->mstat < HAVEIP) {
  1385.             netposterr(806);                /* informative */
  1386.             return(NULL);
  1387.         }
  1388.     }
  1389.  
  1390.     if (!m) {
  1391.         m = Shostlook("default");
  1392.         movebytes(m->hostip,ipto,4);        /* copy in newest host # */
  1393.         m->mstat = HAVEIP;                    /* we have the IP # */
  1394.     }
  1395.  
  1396.     return(m);
  1397. }
  1398.  
  1399. /************************************************************************/
  1400. /*  Slooknum
  1401. *   get the host record by machine number, used primarily in DOMAIN name
  1402. *   lookup.
  1403. */
  1404. struct machinfo 
  1405. *Slooknum(num)
  1406.     int num;
  1407.     {
  1408.     struct machinfo *m;
  1409.  
  1410.     m = Smachlist;
  1411.     while (m) {
  1412.         if (m->mno == num)
  1413.             return(m);
  1414.         m = m->next;
  1415.     }
  1416.  
  1417.     return(NULL);
  1418.  
  1419. }
  1420.  
  1421. /**************************************************************************/
  1422. /*  Slookip
  1423. *   For FTP to look up the transfer options to use when running
  1424. *
  1425. */
  1426. struct machinfo 
  1427. *Slookip(ipnum)
  1428.     unsigned char *ipnum;
  1429.     {
  1430.     struct machinfo *m;
  1431.  
  1432.     m = Smachlist;
  1433.     while (m) {
  1434.         if (comparen(m->hostip,ipnum,4))
  1435.             return(m);
  1436.         m = m->next;
  1437.     }
  1438.  
  1439.     return(NULL);
  1440.  
  1441. }
  1442.  
  1443. /*********************************************************************/
  1444. /*  Snewns()
  1445. *   Rotate to the next nameserver
  1446. *   Chooses the next highest number from the nameserv field
  1447. */
  1448. int Snewns
  1449.   (
  1450.     void
  1451.   )
  1452.     {
  1453.     struct machinfo *m,*low;
  1454.     int i;
  1455.  
  1456.     if (!Sns)                    /* safety, should never happen */
  1457.         Sns = Smachlist;
  1458.  
  1459.     low = Sns;
  1460.     i = Sns->nameserv;            /* what is value now? */
  1461.  
  1462.     m = Smachlist;
  1463.     while (m) {
  1464.         if (m->nameserv == i+1) {
  1465.             Sns = m;
  1466.             return(0);
  1467.         }
  1468.         if ((m->nameserv > 0) && (m->nameserv < low->nameserv))
  1469.             low = m;
  1470.         m = m->next;
  1471.     }
  1472.  
  1473.     if (Sns == low)
  1474.         return(1);                /* no alternate */
  1475.     else
  1476.         Sns = low;
  1477.  
  1478.     return(0);
  1479. }
  1480.  
  1481. int Ssetns
  1482.   (
  1483.     unsigned char ipn[4]
  1484.   )
  1485.   /* saves the IP address of a name server for future use,
  1486.     returning 1 if I already have it, 0 if not. */
  1487.     {
  1488.     struct machinfo *m;
  1489.     int i;
  1490.  
  1491.     i = 0;
  1492.     if (NULL == (m = Slookip(ipn))) {        /* have already? */
  1493.         m = Smadd("=nameserv=");
  1494.         movebytes(m->hostip,ipn,4);
  1495.         m->mstat = FROMKIP;
  1496.         i = 1;
  1497.     }
  1498.  
  1499.     m->nameserv = 1;
  1500.     Sns = m;
  1501.  
  1502.     return(i);
  1503. }
  1504.  
  1505. /************************************************************************/
  1506. /*  setgates
  1507. *   set up the gateway machines and the subnet mask after netinit()
  1508. *   and start up ftp and rcp for them.
  1509. */
  1510. void Ssetgates
  1511.   (
  1512.     void
  1513.   )
  1514.     {
  1515.     struct machinfo *m;
  1516.     int level,again;
  1517.  
  1518.     if (Scon.havemask)                    /* leave default unless specified */
  1519.         netsetmask(Scon.netmask);
  1520. /*
  1521. *  Search the list of machines for gateway flags.
  1522. *  Invoke netsetgate in increasing order of gateway level #s.
  1523. *  Terminates when it gets through list without finding next higher number.
  1524. */
  1525.     level = 0;
  1526.     do {
  1527.         level++;
  1528.         again = 0;
  1529.         m = Smachlist;
  1530.         while (m != NULL) {
  1531.             if (m->gateway == level && m->mstat >= HAVEIP) 
  1532.                 netsetgate(m->hostip);
  1533.             if (m->gateway == level+1)
  1534.                 again=1;
  1535.             m = m->next;
  1536.         }
  1537.     } while (again);
  1538.  
  1539.     Sftpmode(Scon.ftp);
  1540. #ifdef PC
  1541.     Srcpmode(Scon.rcp);
  1542. #endif
  1543.     /* return(0); */
  1544. }
  1545.